package com.yy.tech.data.provider;

import com.fasterxml.jackson.core.type.TypeReference;
import com.yy.tech.data.context.DesensitizeContext;
import com.yy.tech.data.context.SecretContent;
import com.yy.tech.data.provider.loader.AbstractResourceLoader;
import com.yy.tech.data.provider.loader.JsonRuleResourceLoader;
import com.yy.tech.data.provider.loader.ResourceLoader;
import com.yy.tech.data.provider.model.FindCondition;
import com.yy.tech.data.provider.model.SecretRule;
import com.yy.tech.data.provider.model.SecretRules;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;

/**
 * @author yy
 * @date 2022/4/18
 * @description: TODO
 */
public interface DesensitizeProvider {

    SecretRule findRule(FindCondition condition);

    @Component
    @Order(49)
    class EnvDesensitizeProvider implements DesensitizeProvider {

        @Autowired
        private Environment env;
        @Autowired
        private DesensitizeContext context;

        private SecretRule envRule;
        @PostConstruct
        public void initialize(){
            String keys = env.getProperty(SecretContent.KEY_DESENSITIZE_SECRET_PROPERTIES);
            String encoder=env.getProperty(SecretContent.KEY_DESENSITIZE_SECRET_ENCODER,SecretContent.ENCODER_AES256);
            String decoder=env.getProperty(SecretContent.KEY_DESENSITIZE_SECRET_DECODER,SecretContent.DECODER_AES256);
            String excludes=env.getProperty(SecretContent.KEY_DESENSITIZE_SECRET_EXCLUDES);
            envRule = new SecretRule();
            envRule.setEncoder(encoder);
            envRule.setDecoder(decoder);
            if (StringUtils.hasLength(keys)){
                envRule.setEncrypts(Arrays.asList(keys.split(",")));
            }
            if (StringUtils.hasLength(excludes)){
                envRule.setExcludes(Arrays.asList(excludes.split(",")));
            }
        }
        @Override
        public SecretRule findRule(final FindCondition condition) {
            return (null != envRule &&envRule.match(condition))?envRule:null;
        }
    }

    @Component
    @Order(40)
    class JsonDesensitizeProvider implements DesensitizeProvider, InitializingBean {
        @Autowired
        private Environment env;
        @Resource(name= JsonRuleResourceLoader.BEAN_NAME)
        private ResourceLoader loader;
        private List<SecretRules> rules;
        @Override
        public SecretRule findRule(final FindCondition condition) {
            if (!CollectionUtils.isEmpty(rules)){
                for (SecretRules secretRules :rules){
                    SecretRule rule = secretRules.findRule(condition);
                    if (null != rule){
                        return rule;
                    }
                }
            }
            return null;
        }

        @Override
        public void afterPropertiesSet() throws Exception {
            if (null != loader){
                String dir = env.getProperty(SecretContent.KEY_DESENSITIZE_RESOURCE_DIR,SecretContent.DEFAULT_RESOURCE_DIR);
                String post = env.getProperty(SecretContent.KEY_DESENSITIZE_RESOURCE_POST,SecretContent.DEFAULT_RESOURCE_POST);
                rules = loader.load(dir,post, new TypeReference<SecretRules>() {
                });
            }
        }
    }
}
